package com.demo.example;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * <p> @Title AESUtil
 * <p> @Description AES对称加解密
 *
 * @author tia.bin
 * @date 2022/7/8 11:52
 */
@Slf4j
public class AESUtil {

    private static final Logger logger = LoggerFactory.getLogger(AESUtil.class);

    private static final String DEFAULT_AES_KEY = "bbP6Usewcg6ccIzv";
    private static final String DEFAULT_IV = "ARwBvAG8AZwBsAGU";


    public static void main(String[] args) {
        String s = "This is a Test.";
        String encrypt = encrypt(s, DEFAULT_AES_KEY, DEFAULT_IV);
        String decrypt = decrypt(encrypt, DEFAULT_AES_KEY, DEFAULT_IV);
        System.out.println("after encrypt: " + encrypt);
        System.out.println("after decrypt: " + decrypt);
        System.out.println();

    }

    /**
     * 加密
     *
     * @param content 待加密内容
     * @param key 加密key
     * @param iv 加密iv
     * @return 加密后内容
     */
    private static String encrypt(String content, String key, String iv) {
        try {
            byte[] contentBytes = content.getBytes();
            byte[] keyBytes = key.getBytes();
            byte[] ivBytes = iv.getBytes();
            SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
            // 获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte[] byteEncode = contentBytes;
            byte[] byteAES = cipher.doFinal(byteEncode);
            return Hex.encodeHexString(byteAES, false);
        } catch (Exception e) {
            logger.error("aes encrypt error, {}", e.getMessage(), e);
            return null;
        }
    }


    /**
     * 解密
     *
     * @param content 待解密内容
     * @param key 解密key
     * @param iv 解密iv
     * @return 解密后内容
     */
    private static String decrypt(String content, String key, String iv) {
        try {
            byte[] keyBytes = key.getBytes();
            byte[] ivBytes = iv.getBytes();
            SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
            byte[] byteContent = Hex.decodeHex(content);
            byte[] byteDecode = cipher.doFinal(byteContent);
            return new String(byteDecode);
        } catch (Exception e) {
            logger.error("aes decrypt error, {}", e.getMessage(), e);
            return null;
        }
    }

}
